﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Microsoft.AspNet.SignalR;
using TresEnRaya.Data;

namespace TresEnRaya
{
    public class PartidaHub : Hub
    {
        private readonly static Lazy<DatosPartida> _datos = new Lazy<DatosPartida>(true);
        public DatosPartida Datos { get { return _datos.Value; } }

        public Jugador NuevaPartida(string pais, string nombre)
        {
            var jugador = Datos.NuevoJugador(pais, nombre, Context.ConnectionId);
            var solicitud=Datos.NuevaSolicitud(jugador);
            Clients.All.Nueva(solicitud);
            return jugador;
        }

        public IEnumerable<Jugador> PartidasDisponibles(string pais)
        {
            return Datos.ListaDisponibles(pais);
        }

        public bool Jugar(string pais, string jugador1, string jugador2)
        {
            var solicitud = Datos.ObtenerSolicitud(pais, jugador1);
            if (solicitud != null)
            {
                var jugadorB=Datos.ObtenerJugador(pais, Context.ConnectionId);
                if (jugadorB == null)
                    jugadorB = Datos.NuevoJugador(pais, jugador2, Context.ConnectionId);
                Partida partida = Datos.EmpezarPartida(pais, solicitud, jugadorB);

                //eliminamos las solicitudes pendientes de los jugadores
                Datos.BorrarSolicitud(solicitud);
                var solicitud2 = Datos.ObtenerSolicitud(jugadorB.Pais, jugadorB.Nombre);
                if (solicitud2 != null)
                {
                    Datos.BorrarSolicitud(solicitud2);
                }

                //notificacmos solicitudes eliminadas
                Clients.All.PartidaEliminada(solicitud);
                if (solicitud2 != null)
                {
                    Clients.All.PartidaEliminada(solicitud2);
                }
                //notificamos al llamante sobre el comienzo de la partida
                Clients.Caller.Jugando(partida);
                //notificamos al jugador que solicitó una partida sobre el comienzo de la misma
                Clients.Client(solicitud.Id).Jugando(partida);
                return true;
            }
            else
            {
                error("Ya no existe la partida");
            }
            return false;
        }

        public void MarcaCasilla(string pais, string nombre, int x, int y)
        {

            var partida = Datos.ObtenerPartida(pais, nombre);

            if (partida != null)
            {
                int turno = 0;
                if (Context.ConnectionId == partida.Jugador2.Id)
                    turno = 1;
                int turnoAnterior = partida.Turno;

                try
                {
                    bool acabada = partida.Marcar(x, y, turno);
                    Datos.GuardarMovimiento(partida);
                    Clients.Client(partida.Jugador1.Id).Jugada(partida);
                    Clients.Client(partida.Jugador2.Id).Jugada(partida);

                    if (acabada)
                    {
                        switch (partida.Estado)
                        {
                            case EstadoPartida.Empate:
                                Clients.Client(partida.Jugador1.Id).FinJuego("Esta vez hay empate");
                                Clients.Client(partida.Jugador2.Id).FinJuego("Esta vez hay empate");
                                break;
                            case EstadoPartida.Gana1:
                                Clients.Client(partida.Jugador1.Id).FinJuego("Ganaste la partida!!!");
                                Clients.Client(partida.Jugador2.Id).FinJuego("Esta vez te ganó " + partida.Jugador1.Nombre);
                                break;
                            case EstadoPartida.Gana2:
                                Clients.Client(partida.Jugador2.Id).FinJuego("Ganaste la partida!!!");
                                Clients.Client(partida.Jugador1.Id).FinJuego("Esta vez te ganó " + partida.Jugador2.Nombre);
                                break;
                        }
                    }
                }
                catch (InvalidOperationException ex)
                {
                    mensaje(ex.Message);
                }
            }
            else
            {
                error("no existe la partida");
            }
        }

        private void error(string error)
        {
            mensaje("Error: " + error);
        }

        private void mensaje(string msg)
        {
            Clients.Caller.Mensaje(msg);
        }
    }
}